package com.zenithmind.library.config;

import lombok.Getter;
import org.springframework.stereotype.Component;

/**
 * 图书馆安全端点配置
 * 遵循单一职责原则：只负责端点路径的定义和管理
 * 遵循开闭原则：新增端点只需在此类中添加，不需要修改其他代码
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Getter
@Component
public class LibrarySecurityEndpoints {

    /**
     * OpenAPI文档相关端点
     */
    private final String[] authWhitelist = {
        // SpringDoc OpenAPI endpoints
        "/v3/api-docs/**",
        "/swagger-ui/**",
        "/swagger-ui.html",
        "/doc.html",
        "/webjars/**",
        // Knife4j endpoints
        "/favicon.ico",
        "/knife4j/**",
        "/knife4j-ui/**",
        "/knife4j.html"
    };

    /**
     * 公开端点配置 - 不需要认证的端点
     */
    private final String[] publicEndpoints = {
        // 图书公开查询端点 - 允许游客浏览
        "/api/zenithMind/v1/books/public/**",
        "/api/zenithMind/v1/books/search",
        "/api/zenithMind/v1/books/categories",
        "/api/zenithMind/v1/books/popular",
        "/api/zenithMind/v1/books/recommended",
        "/api/zenithMind/v1/books/new",
        "/api/zenithMind/v1/books/*/preview",
        // 作者公开端点
        "/api/zenithMind/v1/authors/public/**",
        "/api/zenithMind/v1/authors/search",
        "/api/zenithMind/v1/authors/hot",
        "/api/zenithMind/v1/authors/productive",
        // 图书分类公开端点
        "/api/zenithMind/v1/categories/public/**",
        "/api/zenithMind/v1/categories/tree",
        // 出版社公开端点
        "/api/zenithMind/v1/publishers/public/**",
        "/api/zenithMind/v1/publishers/search",
        // 借阅记录公开统计端点
        "/api/zenithMind/v1/borrows/statistics/public",
        // 健康检查和其他公开端点
        "/actuator/**",
        "/health",
        "/info"
    };
    
    /**
     * 需要用户角色的端点
     */
    private final String[] userEndpoints = {
        "/api/zenithMind/v1/books/**",
        "/api/zenithMind/v1/authors/**",
        "/api/zenithMind/v1/categories/**",
        "/api/zenithMind/v1/publishers/**",
        "/api/zenithMind/v1/borrows/**",
        "/api/zenithMind/v1/reservations/**"
    };
    
    /**
     * 需要图书管理员角色的端点
     */
    private final String[] librarianEndpoints = {
        // 图书管理
        "/api/zenithMind/v1/books",
        "/api/zenithMind/v1/books/*/edit",
        "/api/zenithMind/v1/books/*/publish",
        "/api/zenithMind/v1/books/*/unpublish",
        "/api/zenithMind/v1/books/*/recommend",
        "/api/zenithMind/v1/books/*/unrecommend",
        "/api/zenithMind/v1/books/*/stock",
        "/api/zenithMind/v1/books/*/rating",
        // 作者管理
        "/api/zenithMind/v1/authors",
        "/api/zenithMind/v1/authors/*/edit",
        "/api/zenithMind/v1/authors/*/enable",
        "/api/zenithMind/v1/authors/*/disable",
        // 分类管理
        "/api/zenithMind/v1/categories",
        "/api/zenithMind/v1/categories/*/edit",
        // 出版社管理
        "/api/zenithMind/v1/publishers",
        "/api/zenithMind/v1/publishers/*/edit",
        // 借阅管理
        "/api/zenithMind/v1/borrows/*/approve",
        "/api/zenithMind/v1/borrows/*/return",
        "/api/zenithMind/v1/borrows/*/renew",
        // 预约管理
        "/api/zenithMind/v1/reservations/*/approve",
        "/api/zenithMind/v1/reservations/*/cancel"
    };
    
    /**
     * 需要管理员角色的端点
     */
    private final String[] adminEndpoints = {
        // 图书管理员功能
        "/api/zenithMind/v1/books/*/delete",
        "/api/zenithMind/v1/books/batch",
        "/api/zenithMind/v1/books/import",
        "/api/zenithMind/v1/books/export",
        // 作者管理员功能
        "/api/zenithMind/v1/authors/*/delete",
        "/api/zenithMind/v1/authors/batch",
        "/api/zenithMind/v1/authors/import",
        "/api/zenithMind/v1/authors/export",
        // 分类管理员功能
        "/api/zenithMind/v1/categories/*/delete",
        "/api/zenithMind/v1/categories/batch",
        // 出版社管理员功能
        "/api/zenithMind/v1/publishers/*/delete",
        "/api/zenithMind/v1/publishers/batch",
        // 系统管理功能
        "/api/zenithMind/v1/manage/**",
        "/api/zenithMind/v1/admin/**"
    };

    /**
     * 获取所有需要跳过认证的端点
     * 包括文档端点和公开端点
     */
    public String[] getAllPublicEndpoints() {
        String[] combined = new String[authWhitelist.length + publicEndpoints.length];
        System.arraycopy(authWhitelist, 0, combined, 0, authWhitelist.length);
        System.arraycopy(publicEndpoints, 0, combined, authWhitelist.length, publicEndpoints.length);
        return combined;
    }

    /**
     * 检查端点是否为公开端点
     */
    public boolean isPublicEndpoint(String path) {
        if (path == null) {
            return false;
        }
        
        // 检查文档端点
        for (String pattern : authWhitelist) {
            if (pathMatches(path, pattern)) {
                return true;
            }
        }
        
        // 检查公开端点
        for (String pattern : publicEndpoints) {
            if (pathMatches(path, pattern)) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 简单的路径匹配逻辑
     * 支持 ** 和 * 通配符
     */
    private boolean pathMatches(String path, String pattern) {
        if (pattern.equals(path)) {
            return true;
        }
        
        if (pattern.endsWith("/**")) {
            String prefix = pattern.substring(0, pattern.length() - 3);
            return path.startsWith(prefix);
        }
        
        if (pattern.contains("*")) {
            // 简单的通配符匹配，实际项目中可以使用更复杂的匹配逻辑
            String regex = pattern.replace("*", ".*");
            return path.matches(regex);
        }
        
        return false;
    }

    /**
     * 获取端点的权限要求描述
     */
    public String getEndpointPermissionDescription(String path) {
        if (isPublicEndpoint(path)) {
            return "公开访问";
        }
        
        for (String pattern : adminEndpoints) {
            if (pathMatches(path, pattern)) {
                return "需要管理员权限";
            }
        }
        
        for (String pattern : librarianEndpoints) {
            if (pathMatches(path, pattern)) {
                return "需要图书管理员权限";
            }
        }
        
        for (String pattern : userEndpoints) {
            if (pathMatches(path, pattern)) {
                return "需要用户权限";
            }
        }
        
        return "需要认证";
    }
}
